home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / libs / sphigs / sph_mac.hqx / SRGP port to 5.0 (compressed) / SRGP_SPHIGS Root / MacSPHIGS / sph_edit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-13  |  8.8 KB  |  372 lines

  1. #include "HEADERS.h"
  2. #include "sphigslocal.h"
  3. #include <string.h> 
  4.  
  5. #include "sph_edit.proto.h"
  6. static void SPH_cleanup_and_kill_element(element *);
  7.  
  8. static element *element_ptr;
  9. static int      element_ptr_index;
  10.  
  11. static substruct_bitstring possible_no_longer_child = NULL;
  12.  
  13. int ID_of_open_struct;
  14. structure *OPENSTRUCT;
  15.  
  16.  
  17.  
  18. element *SPH__currentElementDirectAccess (void)
  19. {
  20.    return element_ptr;
  21. }
  22.  
  23.  
  24.  
  25.  
  26. /** SPH_cleanup_and_kill_element
  27. Frees up any malloc'd areas associated with an element.
  28. **/
  29.  
  30. static void SPH_cleanup_and_kill_element (element *elptr)
  31. {
  32.    switch (elptr->type) {
  33.       
  34.     case ELTYP__POLYHEDRON:
  35.       SPH__freePolyhedron (elptr->data.poly);
  36.       break;
  37.  
  38.     case ELTYP__POLYMARKER:
  39.     case ELTYP__POLYLINE:
  40.     case ELTYP__FILL_AREA:
  41.       free (elptr->data.points);
  42.       break;
  43.  
  44.     case ELTYP__EXECUTE_STRUCTURE:
  45.       SPH__structureTable[elptr->data.value].refcount--;
  46.       SetBit (possible_no_longer_child, elptr->data.value);
  47.       break;
  48.       
  49.    }
  50.  
  51.    free (elptr);
  52. }
  53.  
  54.  
  55.  
  56.  
  57. /** SPH_inquireElptr
  58. **/
  59. int
  60. SPH_inquireElementPointer (void)
  61. {
  62.    SPH_check_system_state;
  63.    SPH_check_open_structure;
  64.    return element_ptr_index;
  65. }
  66.  
  67.  
  68. /** SPH_init_structure_table
  69. All structures exist initially; they're simply empty.
  70. **/
  71. void
  72. SPH__init_structure_table (void)
  73. {
  74.    register i;
  75.  
  76.    bzero (SPH__structureTable, sizeof(structure)*(MAX_STRUCTURE_ID+1));
  77.    for (i=0; i<=MAX_STRUCTURE_ID; i++) {
  78.       ClearBitstring (&(SPH__structureTable[i].child_list));
  79.    }
  80. }
  81.  
  82.  
  83.  
  84.  
  85. /** INTERNAL USE ONLY: SPH__insertElement
  86. Inserts given element in the currently open structure so that it
  87.    follows the currently active element.
  88. Because internal-use only, ASSUMES THERE IS AN OPEN STRUCTURE.
  89. **/
  90.  
  91. void
  92. SPH__insertElement (element *baby)
  93. {
  94.    if (element_ptr == NULL) {
  95.       /* BEING INSERTED AT VERY BEGINNING OF STRUCTURE */
  96.       baby->next = OPENSTRUCT->first_element;
  97.       OPENSTRUCT->first_element = baby;
  98.       baby->previous = NULL;
  99.    }
  100.    else {
  101.       /* BEING INSERTED AFTER AT LEAST ONE EXTANT ELEMENT */
  102.       baby->next = element_ptr->next;
  103.       element_ptr->next = baby;
  104.       baby->previous = element_ptr;
  105.    }
  106.  
  107.    OPENSTRUCT->element_count++;
  108.    if (baby->next == NULL)
  109.       OPENSTRUCT->last_element = baby;
  110.    else
  111.       baby->next->previous = baby;
  112.    element_ptr = baby;
  113.    element_ptr_index++;
  114. }
  115.  
  116.  
  117. /** SPH_openStructure
  118. **/
  119. void
  120. SPH_openStructure (int structID)
  121. {
  122.    SPH_check_system_state;
  123.    SPH_check_no_open_structure;
  124.    SPH_check_structure_id;
  125.  
  126.    ID_of_open_struct = structID;
  127.    OPENSTRUCT = &(SPH__structureTable[structID]);
  128.    element_ptr_index = OPENSTRUCT->element_count;
  129.    element_ptr = OPENSTRUCT->last_element;
  130.    SPH__structureCurrentlyOpen = TRUE;
  131.  
  132.    if (NULL == possible_no_longer_child)
  133.       possible_no_longer_child = (unsigned char*) malloc (BYTES_PER_BITSTRING);
  134.  
  135.    ClearBitstring (&possible_no_longer_child);
  136. }
  137.    
  138.  
  139. static substruct_bitstring BB = NULL;
  140.  
  141.  
  142. /** SPH_closeStructure
  143. **/
  144. void
  145. SPH_closeStructure (void)
  146. {
  147.    SPH_check_system_state;
  148.    SPH_check_open_structure;
  149.  
  150.    /* IF AN INVOCATION WAS DESTROYED BY THE EDITING.... */
  151.    if ( ! BitstringIsClear(possible_no_longer_child)) {
  152.       register element *elptr;
  153.  
  154.  
  155.       /* RECALC CHILD_LIST */
  156.       ClearBitstring (&(OPENSTRUCT->child_list));
  157.       elptr = OPENSTRUCT->first_element;
  158.       while (elptr) {
  159.           if (elptr->type == ELTYP__EXECUTE_STRUCTURE)
  160.              SetBit (OPENSTRUCT->child_list, elptr->data.value);
  161.          elptr = elptr->next;
  162.       }
  163.       
  164.       /* TEST FOR OBSOLESCENCE OF DEPENDENCIES. */
  165.       ClearBitstring (&BB);  /* forces a malloc the 1st time around */
  166.       AndBitstrings (BB, possible_no_longer_child, OPENSTRUCT->child_list);
  167.       /* NOW: BB is a list of all structures that are definitely
  168.        *   children AND that were suspected of having been lost by
  169.        *   a deletion of an invocation.
  170.        * IF BB is equal to the list of all structures suspected of
  171.        *   having been lost, then it must be true that NO
  172.        *   children were lost due to editing in this session.
  173.        * IF BB is NOT equal to...,  then it must be true that
  174.        *   at least one child was lost, and some views' descendent-lists
  175.        *   may now be obsolete!
  176.        */
  177.       if ( ! BitstringsAreEqual (BB, possible_no_longer_child)) 
  178.          /* All views that own S now have obsolete descendent lists! */
  179.          VIEWOPT__afterChildLoss (ID_of_open_struct);
  180.    }
  181.  
  182.    SPH__structureCurrentlyOpen = FALSE;
  183.    SPH__refresh_structure_close (ID_of_open_struct);
  184. }
  185.  
  186.  
  187.  
  188. /** SPH_setElptr
  189. Special case: 0 means set elptr to even before the very first element.
  190.               1 means set elptr to very first element.
  191. **/
  192. void
  193. SPH_setElementPointer (int index)
  194. {
  195.    register i;
  196.  
  197.    SPH_check_system_state;
  198.    SPH_check_open_structure;
  199.  
  200.    if (index == 0)
  201.       element_ptr = NULL;
  202.    else
  203.       if ((index > OPENSTRUCT->element_count) || (index < 0))
  204.      SPH__error (ERR_BAD_SET_ELPTR);
  205.       else {
  206.      element_ptr = OPENSTRUCT->first_element;
  207.      for (i=1; i<index; i++)
  208.         element_ptr = element_ptr->next;
  209.       }
  210.  
  211.    element_ptr_index = index;
  212. }
  213.       
  214.  
  215.  
  216. /** SPH_offsetElptr
  217. Its internal call to SPH_setElptr does the verification work on the index.
  218. **/
  219. void
  220. SPH_offsetElementPointer (int delta)
  221. {
  222.    SPH_check_system_state;
  223.    SPH_check_open_structure;
  224.  
  225.    element_ptr_index += delta;
  226.    SPH_setElementPointer (element_ptr_index);
  227. }
  228.  
  229.  
  230. /** SPH_moveElptrToLabel
  231. Question: should I include the current element in the search?  Or does
  232. the search begin with the first element after the current one?
  233.  
  234. This version does NOT include the current element in the search.
  235. This version gives fatal error if label not found.
  236. **/
  237. void
  238. SPH_moveElementPointerToLabel (int lab)
  239. {
  240.    SPH_check_system_state;
  241.    SPH_check_open_structure;
  242.  
  243.    while (1) {
  244.       /* ADVANCE ELEMENT POINTER */
  245.       element_ptr_index++;
  246.       if (element_ptr_index == 1)
  247.      element_ptr = OPENSTRUCT->first_element;
  248.       else
  249.      element_ptr = element_ptr->next;
  250.  
  251.       if ( ! element_ptr)
  252.      /* REACHED END: NOT FOUND: FATAL ERROR */
  253.      SPH__error (ERR_LABEL_NOT_FOUND);
  254.       
  255.       if (  (element_ptr->type == ELTYP__LABEL)
  256.      && (element_ptr->data.value == lab) )
  257.         /* FOUND */
  258.         break;
  259.    }
  260. }
  261.  
  262.  
  263.  
  264.  
  265. /** SPH_deleteEl
  266. Element pointer is left pointing to the element (if any) just before
  267.    the one to be killed.
  268. **/
  269. void
  270. SPH_deleteElement (void)
  271. {
  272.    element *el_to_die;
  273.  
  274.    SPH_check_system_state;
  275.    SPH_check_open_structure;
  276.    if (element_ptr == NULL)
  277.       SPH__error (ERR_NO_ELEMENT_TO_DELETE);
  278.  
  279.    /* FIRST, HANDLE ITS RELATIONSHIP TO ITS PREVIOUS ELEMENTS */
  280.    if (element_ptr->previous == NULL)
  281.       OPENSTRUCT->first_element = element_ptr->next;
  282.    else
  283.       element_ptr->previous->next = element_ptr->next;
  284.    /* THEN, HANDLE ITS RELATIONSHIP TO ITS NEXT ELEMENTS */
  285.    if (element_ptr->next == NULL)
  286.       OPENSTRUCT->last_element = element_ptr->previous;
  287.    else
  288.       element_ptr->next->previous = element_ptr->previous;
  289.  
  290.    /* UPDATE ELEMENT-COUNT AND ELEMENT-POINTER */
  291.    OPENSTRUCT->element_count--;
  292.    el_to_die = element_ptr;
  293.    element_ptr = el_to_die->previous;
  294.    element_ptr_index--;
  295.  
  296.  
  297.    SPH_cleanup_and_kill_element (el_to_die);
  298. }
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305. /** SPH_deleteElsInRange
  306. **/
  307. void
  308. SPH_deleteElementsInRange (int first_index, int second_index)
  309. {
  310.    element *first_el_to_die, *last_el_to_die;
  311. #define number_to_be_killed    (second_index - first_index + 1)
  312.  
  313.    SPH_check_system_state;
  314.    SPH_check_open_structure;
  315.    
  316.    SPH_setElementPointer (first_index);
  317.    first_el_to_die = element_ptr;
  318.    SPH_setElementPointer (second_index);
  319.    last_el_to_die = element_ptr;
  320.  
  321.    SPH_check_elindex_range;
  322.  
  323.    /* FIRST, HANDLE ITS RELATIONSHIP TO ITS PREVIOUS ELEMENTS */
  324.    if (first_el_to_die->previous == NULL)
  325.       OPENSTRUCT->first_element = last_el_to_die->next;
  326.    else
  327.       first_el_to_die->previous->next = last_el_to_die->next;
  328.  
  329.    /* THEN, HANDLE ITS RELATIONSHIP TO ITS NEXT ELEMENTS */
  330.    if (last_el_to_die->next == NULL)
  331.       OPENSTRUCT->last_element = first_el_to_die->previous;
  332.    else
  333.       last_el_to_die->next->previous = first_el_to_die->previous;
  334.  
  335.    /* UPDATE ELEMENT-COUNT AND ELEMENT-POINTER */
  336.    OPENSTRUCT->element_count -= number_to_be_killed;
  337.    element_ptr = first_el_to_die->previous;
  338.    element_ptr_index = first_index - 1;
  339.  
  340.    /* KILL AND CLEANUP THE ELEMENTS */
  341.    do {
  342.       SPH_cleanup_and_kill_element (first_el_to_die);
  343.       if (first_el_to_die == last_el_to_die)
  344.      break;
  345.       else
  346.      first_el_to_die = first_el_to_die->next;
  347.    } while (1);
  348. }
  349.  
  350.  
  351.  
  352. /** SPH_deleteElsBetweenLabels
  353. **/
  354. void
  355. SPH_deleteElementsBetweenLabels (int lab1, int lab2)
  356. {
  357.    int first_index, second_index;
  358.  
  359.    SPH_check_system_state;
  360.    SPH_check_open_structure;
  361.  
  362.    SPH_moveElementPointerToLabel (lab1);
  363.    first_index = element_ptr_index;
  364.    SPH_moveElementPointerToLabel (lab2);
  365.    second_index = element_ptr_index;
  366.    if (first_index == (second_index-1))
  367.       /* do nothing: nothing lies between the label elements */;
  368.    else
  369.       SPH_deleteElementsInRange (first_index+1, second_index-1);
  370. }
  371.  
  372.